using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using WMS.Api.Application.Commands;
using WMS.Common;
using WMS.Domain;
using WMS.Infrastructure;

namespace WMS.Api.Application.CommandHandlers
{
    /// <summary>
    /// 获取箱子型号列表命令处理程序
    /// </summary>
    public class GetBoxTypeListCommandHandler : IRequestHandler<GetBoxTypeListCommand, ApiResult<PagingResult<List<BoxTypeDto>>>>
    {
        private readonly MyDBContext _dbContext;
        private readonly IMapper _mapper;
        private readonly ILogger<GetBoxTypeListCommandHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext">数据库上下文</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetBoxTypeListCommandHandler(MyDBContext dbContext, IMapper mapper, ILogger<GetBoxTypeListCommandHandler> logger)
        {
            _dbContext = dbContext;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取箱子型号列表命令
        /// </summary>
        /// <param name="request">请求命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>箱子型号列表分页结果</returns>
        public async Task<ApiResult<PagingResult<List<BoxTypeDto>>>> Handle(GetBoxTypeListCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 构建查询
                var query = _dbContext.BoxType.AsQueryable();

                // 应用筛选条件
                if (!string.IsNullOrEmpty(request.Name))
                {
                    query = query.Where(b => b.Name.Contains(request.Name));
                }

                if (request.Status.HasValue)
                {
                    query = query.Where(b => b.Status == request.Status.Value);
                }

                // 计算总记录数
                var totalCount = await query.CountAsync(cancellationToken);

                // 分页查询
                var boxTypes = await query
                    .OrderByDescending(b => b.Id)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                // 映射为DTO
                var boxTypeDtos = _mapper.Map<List<BoxTypeDto>>(boxTypes);

                // 构建分页结果
                var pagingResult = new PagingResult<List<BoxTypeDto>>
                {
                    data = boxTypeDtos,
                    totalCount = totalCount,
                    totalPage = (int)Math.Ceiling(totalCount / (double)request.PageSize)
                };

                // 返回成功结果
                return new ApiResult<PagingResult<List<BoxTypeDto>>>("获取箱子型号列表成功")
                {
                    code = StatusCodeEnum.Ok,
                    data = pagingResult,
                    isSuc = true
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取箱子型号列表失败");
                return new ApiResult<PagingResult<List<BoxTypeDto>>>("获取箱子型号列表失败：" + ex.Message)
                {
                    code = StatusCodeEnum.Fail,
                    isSuc = false
                };
            }
        }
    }

    /// <summary>
    /// 获取箱子型号详情命令处理程序
    /// </summary>
    public class GetBoxTypeByIdCommandHandler : IRequestHandler<GetBoxTypeByIdCommand, ApiResult<BoxTypeDto>>
    {
        private readonly MyDBContext _dbContext;
        private readonly IMapper _mapper;
        private readonly ILogger<GetBoxTypeByIdCommandHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext">数据库上下文</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetBoxTypeByIdCommandHandler(MyDBContext dbContext, IMapper mapper, ILogger<GetBoxTypeByIdCommandHandler> logger)
        {
            _dbContext = dbContext;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取箱子型号详情命令
        /// </summary>
        /// <param name="request">请求命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>箱子型号详情</returns>
        public async Task<ApiResult<BoxTypeDto>> Handle(GetBoxTypeByIdCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询箱子型号
                var boxType = await _dbContext.BoxType
                    .FirstOrDefaultAsync(b => b.Id == request.Id, cancellationToken);

                if (boxType == null)
                {
                    return new ApiResult<BoxTypeDto>("箱子型号不存在")
                    {
                        code = StatusCodeEnum.DataNotExist,
                        isSuc = false
                    };
                }

                // 映射为DTO
                var boxTypeDto = _mapper.Map<BoxTypeDto>(boxType);

                // 返回成功结果
                return new ApiResult<BoxTypeDto>("获取箱子型号详情成功")
                {
                    code = StatusCodeEnum.Ok,
                    data = boxTypeDto,
                    isSuc = true
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取箱子型号详情失败");
                return new ApiResult<BoxTypeDto>("获取箱子型号详情失败：" + ex.Message)
                {
                    code = StatusCodeEnum.Fail,
                    isSuc = false
                };
            }
        }
    }

    /// <summary>
    /// 创建箱子型号命令处理程序
    /// </summary>
    public class CreateBoxTypeCommandHandler : IRequestHandler<CreateBoxTypeCommand, ApiResult<int>>
    {
        private readonly MyDBContext _dbContext;
        private readonly IMapper _mapper;
        private readonly ILogger<CreateBoxTypeCommandHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext">数据库上下文</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public CreateBoxTypeCommandHandler(MyDBContext dbContext, IMapper mapper, ILogger<CreateBoxTypeCommandHandler> logger)
        {
            _dbContext = dbContext;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理创建箱子型号命令
        /// </summary>
        /// <param name="request">请求命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>创建结果</returns>
        public async Task<ApiResult<int>> Handle(CreateBoxTypeCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 检查名称是否已存在
                var existingBoxType = await _dbContext.BoxType
                    .FirstOrDefaultAsync(b => b.Name == request.BoxType.Name, cancellationToken);

                if (existingBoxType != null)
                {
                    return new ApiResult<int>("箱子型号名称已存在")
                    {
                        code = StatusCodeEnum.DataExist,
                        isSuc = false
                    };
                }

                // 映射为实体
                var boxType = _mapper.Map<BoxType>(request.BoxType);

                // 添加到数据库
                _dbContext.BoxType.Add(boxType);
                await _dbContext.SaveChangesAsync(cancellationToken);

                // 返回成功结果
                return new ApiResult<int>("创建箱子型号成功")
                {
                    code = StatusCodeEnum.Ok,
                    data = boxType.Id,
                    isSuc = true
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建箱子型号失败");
                return new ApiResult<int>("创建箱子型号失败：" + ex.Message)
                {
                    code = StatusCodeEnum.Fail,
                    isSuc = false
                };
            }
        }
    }

    /// <summary>
    /// 更新箱子型号命令处理程序
    /// </summary>
    public class UpdateBoxTypeCommandHandler : IRequestHandler<UpdateBoxTypeCommand, ApiResult<int>>
    {
        private readonly MyDBContext _dbContext;
        private readonly IMapper _mapper;
        private readonly ILogger<UpdateBoxTypeCommandHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext">数据库上下文</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public UpdateBoxTypeCommandHandler(MyDBContext dbContext, IMapper mapper, ILogger<UpdateBoxTypeCommandHandler> logger)
        {
            _dbContext = dbContext;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理更新箱子型号命令
        /// </summary>
        /// <param name="request">请求命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>更新结果</returns>
        public async Task<ApiResult<int>> Handle(UpdateBoxTypeCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询箱子型号
                var boxType = await _dbContext.BoxType
                    .FirstOrDefaultAsync(b => b.Id == request.BoxType.Id, cancellationToken);

                if (boxType == null)
                {
                    return new ApiResult<int>("箱子型号不存在")
                    {
                        code = StatusCodeEnum.DataNotExist,
                        isSuc = false
                    };
                }

                // 检查名称是否已存在（排除当前记录）
                var existingBoxType = await _dbContext.BoxType
                    .FirstOrDefaultAsync(b => b.Name == request.BoxType.Name && b.Id != request.BoxType.Id, cancellationToken);

                if (existingBoxType != null)
                {
                    return new ApiResult<int>("箱子型号名称已存在")
                    {
                        code = StatusCodeEnum.DataExist,
                        isSuc = false
                    };
                }

                // 更新属性
                boxType.Name = request.BoxType.Name;
                boxType.Length = request.BoxType.Length;
                boxType.Width = request.BoxType.Width;
                boxType.Height = request.BoxType.Height;
                boxType.Notes = request.BoxType.Notes;
                boxType.Status = request.BoxType.Status;

                // 保存更改
                await _dbContext.SaveChangesAsync(cancellationToken);

                // 返回成功结果
                return new ApiResult<int>("更新箱子型号成功")
                {
                    code = StatusCodeEnum.Ok,
                    data = boxType.Id,
                    isSuc = true
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新箱子型号失败");
                return new ApiResult<int>("更新箱子型号失败：" + ex.Message)
                {
                    code = StatusCodeEnum.Fail,
                    isSuc = false
                };
            }
        }
    }

    /// <summary>
    /// 删除箱子型号命令处理程序
    /// </summary>
    public class DeleteBoxTypeCommandHandler : IRequestHandler<DeleteBoxTypeCommand, ApiResult<int>>
    {
        private readonly MyDBContext _dbContext;
        private readonly ILogger<DeleteBoxTypeCommandHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbContext">数据库上下文</param>
        /// <param name="logger">日志记录器</param>
        public DeleteBoxTypeCommandHandler(MyDBContext dbContext, ILogger<DeleteBoxTypeCommandHandler> logger)
        {
            _dbContext = dbContext;
            _logger = logger;
        }

        /// <summary>
        /// 处理删除箱子型号命令
        /// </summary>
        /// <param name="request">请求命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>删除结果</returns>
        public async Task<ApiResult<int>> Handle(DeleteBoxTypeCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询箱子型号
                var boxType = await _dbContext.BoxType
                    .FirstOrDefaultAsync(b => b.Id == request.Id, cancellationToken);

                if (boxType == null)
                {
                    return new ApiResult<int>("箱子型号不存在")
                    {
                        code = StatusCodeEnum.DataNotExist,
                        isSuc = false
                    };
                }

                // 删除箱子型号
                _dbContext.BoxType.Remove(boxType);
                await _dbContext.SaveChangesAsync(cancellationToken);

                // 返回成功结果
                return new ApiResult<int>("删除箱子型号成功")
                {
                    code = StatusCodeEnum.Ok,
                    data = request.Id,
                    isSuc = true
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除箱子型号失败");
                return new ApiResult<int>("删除箱子型号失败：" + ex.Message)
                {
                    code = StatusCodeEnum.Fail,
                    isSuc = false
                };
            }
        }
    }
} 